{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# Visdom Usage\n",
    "\n",
    "## 1. Plot Online Curve"
   ],
   "id": "175e0d30b63b6ea9"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-18T12:02:52.068126Z",
     "start_time": "2025-03-18T12:02:51.243199Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from visdom import Visdom\n",
    "\n",
    "viz = Visdom()\n",
    "viz.line([0.],  ## Y的第一个点坐标\n",
    "         [0.],  ## X的第一个点坐标\n",
    "         win=\"train loss\",  ##窗口名称\n",
    "         opts=dict(title='train_loss')  ## 图像标例\n",
    "         )  #设置起始点\n",
    "'''\n",
    "模型数据\n",
    "'''\n",
    "viz.line([1.],  ## Y的下一个点坐标\n",
    "         [1.],  ## X的下一个点坐标\n",
    "         win=\"train loss\",  ## 窗口名称 与上个窗口同名表示显示在同一个表格里\n",
    "         update='append'  ## 添加到上一个点后面\n",
    "         )"
   ],
   "id": "1850ce2328a0ffc8",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Setting up a new session...\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'train loss'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 1
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 2. Plot Multiple Curves",
   "id": "8e1a76151f72773a"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-18T12:07:08.747252Z",
     "start_time": "2025-03-18T12:07:08.736914Z"
    }
   },
   "cell_type": "code",
   "source": [
    "#设置起始点\n",
    "viz.line([[0.0, 0.0]],  ## Y的起始点\n",
    "         [0.],  ## X的起始点\n",
    "         win=\"test loss\",  ##窗口名称\n",
    "         opts=dict(title='test_loss')  ## 图像标例\n",
    "         )\n",
    "'''\n",
    "模型数据\n",
    "'''\n",
    "viz.line([[1.1, 1.5]],  ## Y的下一个点\n",
    "         [1.],  ## X的下一个点\n",
    "         win=\"test loss\",  ## 窗口名称\n",
    "         update='append'  ## 添加到上一个点后面\n",
    "         )"
   ],
   "id": "5d783fabf28548c4",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'test loss'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 3. Display Images",
   "id": "700a42050a37d7ba"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-18T12:10:21.677319Z",
     "start_time": "2025-03-18T12:10:21.580607Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import numpy as np\n",
    "\n",
    "image = np.random.randn(6, 3, 200, 300)  # 此时batch为6\n",
    "viz.images(image, win='x')"
   ],
   "id": "f87ac4191bd62c28",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'x'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 4. Datasets Visualization",
   "id": "942f1b93b21d570b"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-18T12:13:28.747237Z",
     "start_time": "2025-03-18T12:13:28.172462Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from torchvision import datasets, transforms\n",
    "import torch\n",
    "\n",
    "# 注意数据集路径\n",
    "train_loader = torch.utils.data.DataLoader(datasets.MNIST(\n",
    "    r'./mnist_train',\n",
    "    train=True,\n",
    "    download=False,\n",
    "    transform=transforms.Compose(\n",
    "        [transforms.ToTensor()])), batch_size=128, shuffle=True)\n",
    "sample = next(iter(train_loader))  # 通过迭代器获取样本\n",
    "# sample[0]为样本数据 sample[1]为类别  nrow=16表示每行显示16张图像\n",
    "viz.images(sample[0], nrow=16, win='mnist', opts=dict(title='mnist'))"
   ],
   "id": "6771e8dcffd82daf",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'mnist'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 5. Training",
   "id": "cb736e692a8ebd5"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-18T12:31:47.395815Z",
     "start_time": "2025-03-18T12:31:16.292049Z"
    }
   },
   "cell_type": "code",
   "source": [
    "\n",
    "from torch import nn, optim\n",
    "\n",
    "'''\n",
    "构建简单的模型:简单线性层+Relu函数的多层感知机\n",
    "'''\n",
    "\n",
    "\n",
    "class MLP(nn.Module):\n",
    "\n",
    "    def __init__(self):\n",
    "        super(MLP, self).__init__()\n",
    "\n",
    "        self.model = nn.Sequential(\n",
    "            nn.Linear(784, 200),\n",
    "            nn.ReLU(inplace=True),\n",
    "            nn.Linear(200, 200),\n",
    "            nn.ReLU(inplace=True),\n",
    "            nn.Linear(200, 10),\n",
    "            nn.ReLU(inplace=True),\n",
    "        )\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = self.model(x)\n",
    "\n",
    "        return x\n",
    "\n",
    "\n",
    "batch_size = 128\n",
    "learning_rate = 0.01\n",
    "epochs = 10\n",
    "\n",
    "# 注意数据集路径\n",
    "train_loader = torch.utils.data.DataLoader(datasets.MNIST(\n",
    "    r'./data',\n",
    "    train=True,\n",
    "    download=True,\n",
    "    transform=transforms.Compose(\n",
    "        [transforms.ToTensor(),\n",
    "         transforms.Normalize((0.1307,), (0.3081,))])),\n",
    "    batch_size=batch_size,\n",
    "    shuffle=True)\n",
    "# 注意数据集路径\n",
    "test_loader = torch.utils.data.DataLoader(datasets.MNIST(\n",
    "    r'./data',\n",
    "    train=False,\n",
    "    transform=transforms.Compose(\n",
    "        [transforms.ToTensor(),\n",
    "         transforms.Normalize((0.1307,), (0.3081,))])),\n",
    "    batch_size=batch_size,\n",
    "    shuffle=True)\n",
    "\n",
    "# 注意此处初始化visdom类\n",
    "viz = Visdom(env='MLP')\n",
    "# 绘制起点\n",
    "viz.line([0.], [0.], win=\"train loss\", opts=dict(title='train_loss'))\n",
    "device = 'cuda:0' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'\n",
    "device = torch.device(device)\n",
    "net = MLP().to(device)\n",
    "optimizer = optim.SGD(net.parameters(), lr=learning_rate)\n",
    "criteon = nn.CrossEntropyLoss().to(device)\n",
    "\n",
    "for epoch in range(epochs):\n",
    "\n",
    "    for batch_idx, (data, target) in enumerate(train_loader):\n",
    "        data = data.view(-1, 28 * 28)\n",
    "        data, target = data.to(device), target.to(device)\n",
    "        logits = net(data)\n",
    "        loss = criteon(logits, target)\n",
    "\n",
    "        optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        # print(w1.grad.norm(), w2.grad.norm())\n",
    "        optimizer.step()\n",
    "\n",
    "        if batch_idx % 100 == 0:\n",
    "            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n",
    "                epoch, batch_idx * len(data), len(train_loader.dataset),\n",
    "                       100. * batch_idx / len(train_loader), loss.item()))\n",
    "\n",
    "    test_loss = 0\n",
    "    correct = 0\n",
    "    for data, target in test_loader:\n",
    "        data = data.view(-1, 28 * 28)\n",
    "        data, target = data.to(device), target.to(device)\n",
    "        logits = net(data)\n",
    "        test_loss += criteon(logits, target).item()\n",
    "\n",
    "        pred = logits.argmax(dim=1)\n",
    "        correct += pred.eq(target).float().sum().item()\n",
    "\n",
    "    test_loss /= len(test_loader.dataset)\n",
    "    # 绘制epoch以及对应的测试集损失loss\n",
    "    viz.line([test_loss], [epoch], win=\"train loss\", update='append')\n",
    "    print(\n",
    "        '\\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n",
    "            test_loss, correct, len(test_loader.dataset),\n",
    "            100. * correct / len(test_loader.dataset)))\n"
   ],
   "id": "53588159b506f264",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Setting up a new session...\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Epoch: 0 [0/60000 (0%)]\tLoss: 2.304762\n",
      "Train Epoch: 0 [12800/60000 (21%)]\tLoss: 2.005977\n",
      "Train Epoch: 0 [25600/60000 (43%)]\tLoss: 1.209684\n",
      "Train Epoch: 0 [38400/60000 (64%)]\tLoss: 0.813180\n",
      "Train Epoch: 0 [51200/60000 (85%)]\tLoss: 0.416880\n",
      "\n",
      "Test set: Average loss: 0.0038, Accuracy: 8774.0/10000 (88%)\n",
      "\n",
      "Train Epoch: 1 [0/60000 (0%)]\tLoss: 0.500542\n",
      "Train Epoch: 1 [12800/60000 (21%)]\tLoss: 0.526198\n",
      "Train Epoch: 1 [25600/60000 (43%)]\tLoss: 0.414724\n",
      "Train Epoch: 1 [38400/60000 (64%)]\tLoss: 0.451495\n",
      "Train Epoch: 1 [51200/60000 (85%)]\tLoss: 0.421920\n",
      "\n",
      "Test set: Average loss: 0.0026, Accuracy: 9089.0/10000 (91%)\n",
      "\n",
      "Train Epoch: 2 [0/60000 (0%)]\tLoss: 0.388824\n",
      "Train Epoch: 2 [12800/60000 (21%)]\tLoss: 0.225287\n",
      "Train Epoch: 2 [25600/60000 (43%)]\tLoss: 0.306729\n",
      "Train Epoch: 2 [38400/60000 (64%)]\tLoss: 0.305831\n",
      "Train Epoch: 2 [51200/60000 (85%)]\tLoss: 0.375257\n",
      "\n",
      "Test set: Average loss: 0.0022, Accuracy: 9192.0/10000 (92%)\n",
      "\n",
      "Train Epoch: 3 [0/60000 (0%)]\tLoss: 0.264251\n",
      "Train Epoch: 3 [12800/60000 (21%)]\tLoss: 0.195585\n",
      "Train Epoch: 3 [25600/60000 (43%)]\tLoss: 0.269420\n",
      "Train Epoch: 3 [38400/60000 (64%)]\tLoss: 0.199620\n",
      "Train Epoch: 3 [51200/60000 (85%)]\tLoss: 0.274545\n",
      "\n",
      "Test set: Average loss: 0.0020, Accuracy: 9267.0/10000 (93%)\n",
      "\n",
      "Train Epoch: 4 [0/60000 (0%)]\tLoss: 0.353751\n",
      "Train Epoch: 4 [12800/60000 (21%)]\tLoss: 0.321784\n",
      "Train Epoch: 4 [25600/60000 (43%)]\tLoss: 0.237544\n",
      "Train Epoch: 4 [38400/60000 (64%)]\tLoss: 0.317236\n",
      "Train Epoch: 4 [51200/60000 (85%)]\tLoss: 0.190460\n",
      "\n",
      "Test set: Average loss: 0.0019, Accuracy: 9309.0/10000 (93%)\n",
      "\n",
      "Train Epoch: 5 [0/60000 (0%)]\tLoss: 0.354802\n",
      "Train Epoch: 5 [12800/60000 (21%)]\tLoss: 0.221088\n",
      "Train Epoch: 5 [25600/60000 (43%)]\tLoss: 0.228531\n",
      "Train Epoch: 5 [38400/60000 (64%)]\tLoss: 0.258759\n",
      "Train Epoch: 5 [51200/60000 (85%)]\tLoss: 0.237422\n",
      "\n",
      "Test set: Average loss: 0.0017, Accuracy: 9372.0/10000 (94%)\n",
      "\n",
      "Train Epoch: 6 [0/60000 (0%)]\tLoss: 0.271523\n",
      "Train Epoch: 6 [12800/60000 (21%)]\tLoss: 0.177145\n",
      "Train Epoch: 6 [25600/60000 (43%)]\tLoss: 0.214408\n",
      "Train Epoch: 6 [38400/60000 (64%)]\tLoss: 0.101117\n",
      "Train Epoch: 6 [51200/60000 (85%)]\tLoss: 0.238512\n",
      "\n",
      "Test set: Average loss: 0.0016, Accuracy: 9408.0/10000 (94%)\n",
      "\n",
      "Train Epoch: 7 [0/60000 (0%)]\tLoss: 0.353097\n",
      "Train Epoch: 7 [12800/60000 (21%)]\tLoss: 0.246696\n",
      "Train Epoch: 7 [25600/60000 (43%)]\tLoss: 0.256101\n",
      "Train Epoch: 7 [38400/60000 (64%)]\tLoss: 0.275079\n",
      "Train Epoch: 7 [51200/60000 (85%)]\tLoss: 0.206906\n",
      "\n",
      "Test set: Average loss: 0.0015, Accuracy: 9444.0/10000 (94%)\n",
      "\n",
      "Train Epoch: 8 [0/60000 (0%)]\tLoss: 0.233155\n",
      "Train Epoch: 8 [12800/60000 (21%)]\tLoss: 0.277453\n",
      "Train Epoch: 8 [25600/60000 (43%)]\tLoss: 0.295416\n",
      "Train Epoch: 8 [38400/60000 (64%)]\tLoss: 0.359293\n",
      "Train Epoch: 8 [51200/60000 (85%)]\tLoss: 0.147595\n",
      "\n",
      "Test set: Average loss: 0.0015, Accuracy: 9459.0/10000 (95%)\n",
      "\n",
      "Train Epoch: 9 [0/60000 (0%)]\tLoss: 0.150200\n",
      "Train Epoch: 9 [12800/60000 (21%)]\tLoss: 0.240806\n",
      "Train Epoch: 9 [25600/60000 (43%)]\tLoss: 0.188363\n",
      "Train Epoch: 9 [38400/60000 (64%)]\tLoss: 0.171555\n",
      "Train Epoch: 9 [51200/60000 (85%)]\tLoss: 0.210339\n",
      "\n",
      "Test set: Average loss: 0.0014, Accuracy: 9485.0/10000 (95%)\n",
      "\n"
     ]
    }
   ],
   "execution_count": 7
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
